package nio;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 *非直接缓冲区和直接缓冲区的区别
 *非直接缓冲区在读取和写入文件时，会先把字节复制到内存，再从内存复制到jvm，然后在读进程序，较慢，但安全性较高
 * 直接缓冲区不会来回copy，只需通过映射文件，直接从应用程序通过映射文件写入到物理磁盘，读写速度较快，但安全性较低，
 * **/
public class Demo3 {

    public static void main(String[] args) throws Exception {
        //非直接缓冲区
        nioNo();
        //直接缓冲区
        nioYes();
    }

    static void nioYes() throws IOException {
        Long startTime = System.currentTimeMillis();
        //创建管道(赋予只读权限)
        FileChannel inChannel = FileChannel.open(Paths.get("/Users/mac/Desktop/notLoveMe.mp4"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("/Users/mac/Desktop/notLoveMe2.mp4"),StandardOpenOption.READ,StandardOpenOption.WRITE);
        //定义映射文件
        MappedByteBuffer inMappedByte = inChannel.map(FileChannel.MapMode.READ_ONLY,0,inChannel.size());
        MappedByteBuffer outMappedByte = outChannel.map(FileChannel.MapMode.READ_WRITE,0,inChannel.size());
        //直接对缓冲区进行操作
        byte[] dsf = new byte[inMappedByte.limit()];
        inMappedByte.get(dsf);
        outMappedByte.put(dsf);
        inChannel.close();
        outChannel.close();
        Long endTime = System.currentTimeMillis();//11
        System.out.println("直接缓冲区耗费时间" + (endTime-startTime));
    }


    static void nioNo() throws IOException {
        Long startTime = System.currentTimeMillis();
        //读入流
        FileInputStream fin = new FileInputStream("/Users/mac/Desktop/notLoveMe.mp4");
        //写出流
        FileOutputStream fot = new FileOutputStream("/Users/mac/Desktop/notLoveMe2.mp4");
        //创建通道
        FileChannel inChannel = fin.getChannel();
        FileChannel otChannel = fot.getChannel();
        //分配指定大小缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);
        while(inChannel.read(buf) != -1){
            //开启读取模式
            buf.flip();
            //将数据写入到通道中
            otChannel.write(buf);
            buf.clear();
        }
        //关闭通道，关闭连接
        inChannel.close();
        otChannel.close();
        fin.close();
        fot.close();
        Long endTime = System.currentTimeMillis();
        //356
        System.out.println("非直接缓冲区耗费时间：" + (endTime-startTime));

    }
}
